﻿using KAs.Common.Attr;
using KAs.SqlSugar.Entity;
using KAs.SqlSugar.Entity.Interface;
using Microsoft.AspNetCore.DataProtection.KeyManagement;
using System.Linq.Expressions;
using System.Reflection;

namespace SqlSugar;

/// <summary>
/// sqlsugar扩展
/// </summary>
public static class SqlSugarExtensions
{
    /// <summary>
    /// 通用插入扩展，无需在意使用雪花id或guid、自增id
    /// </summary>
    /// <typeparam name="T">实体类</typeparam>
    /// <typeparam name="TPrimaryKey">主键类型</typeparam>
    /// <param name="insertable"></param>
    /// <returns></returns>
    public static async Task<long> ExcutedReturnIdAsync<T, TPrimaryKey>(this IInsertable<T> insertable)
        where T : Entity<TPrimaryKey>, new()
    {
        //只有添加自动审计特性的实体才会处理自动审计过程
        var diffLogFlag = typeof(T).GetCustomAttribute<AutoAuditAttribute>() != null;
        // 主键为long，雪花Id
        if (typeof(TPrimaryKey) == typeof(long))
            return await insertable.EnableDiffLogEvent(diffLogFlag).ExecuteReturnSnowflakeIdAsync();
        else
            return await insertable.EnableDiffLogEvent(diffLogFlag).ExecuteReturnBigIdentityAsync();
    }

    /// <summary>
    /// 通用更新扩展，增加差异审计判断
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="updateable"></param>
    /// <returns></returns>
    public static async Task<bool> ExecuteCommandAndLogDiffAsync<T>(this IUpdateable<T> updateable)
        where T : class, IEntity, new()
    {
        //只有添加自动审计特性的实体才会处理自动审计过程
        var diffLogFlag = typeof(T).GetCustomAttribute<AutoAuditAttribute>() != null;
        return await updateable.EnableDiffLogEvent(diffLogFlag).ExecuteCommandHasChangeAsync();
    }

    /// <summary>
    /// 通用删除扩展，无需考虑是否为软删除，根据特性自动判断
    /// </summary>
    /// <typeparam name="T">实体类</typeparam>
    /// <typeparam name="TPrimaryKey">主键类型</typeparam>
    /// <param name="deleteable"></param>
    /// <param name="id">主键</param>
    /// <returns></returns>
    public static async Task<bool> DeleteInAsync<T, TPrimaryKey>(this IDeleteable<T> deleteable, TPrimaryKey id)
        where T : Entity<TPrimaryKey>, new()
    {
        //只有添加自动审计特性的实体才会处理自动审计过程
        var diffLogFlag = typeof(T).GetCustomAttribute<AutoAuditAttribute>() != null;
        // 实体继承IDeleteEntity接口，则进行逻辑删除，否则进行物理删除
        if (typeof(T).GetInterfaces().Any(x => x == typeof(IDeleteEntity)))
            return await deleteable.EnableDiffLogEvent(diffLogFlag).In(id).IsLogic().ExecuteCommandAsync() > 0;
        else
            return await deleteable.EnableDiffLogEvent(diffLogFlag).In(id).ExecuteCommandHasChangeAsync();
    }

    /// <summary>
    /// 分页请求排序Dic扩展
    /// </summary>
    /// <typeparam name="TSource">实体</typeparam>
    /// <param name="orderDic"></param>
    /// <param name="keySelector">实体属性</param>
    /// <param name="type">排序类型</param>
    /// <remarks>
    /// 防止在编码中添加排序dic时使用string型不准确
    /// </remarks>
    public static void OrderDicAppend<TSource>(this IDictionary<string, string> orderDic,
        Expression<Func<TSource, object>> keySelector, OrderByType type = OrderByType.Asc)
    {
        var keyName = string.Empty;
        if (keySelector.Body is UnaryExpression unaryExp)
        {
            keyName = ((MemberExpression)unaryExp.Operand).Member.Name;
        }
        else if (keySelector.Body is MemberExpression memberExp)
        {
            keyName = memberExp.Member.Name;
        }
        else if (keySelector.Body is ParameterExpression paramExp)
        {
            keyName = paramExp.Type.Name;
        }
        orderDic.Add(keyName, type == OrderByType.Asc ? "asc" : "desc");
    }
}